package com.sunyard.manage.apk;

import com.alibaba.fastjson.JSONObject;
import com.sunyard.dal.dto.znsTask.TaskZNSDTO;
import com.sunyard.dal.entity.OperateHistory;
import com.sunyard.dal.entity.Terminal;
import com.sunyard.dal.mapper.OperateHistoryMapper;
import com.sunyard.dal.mapper.TerminalMapper;
import com.sunyard.dal.mapper.ZNSTaskMapper;
import com.sunyard.manage.service.BoxAlarmService;
import com.sunyard.utils.CrcUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigInteger;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @author: ZhangShuai
 * @description:获取物联网平台请求数据中参数（尾箱经纬度，门锁开关，电量）
 * @create: 2022-07-20 16:23
 **/
@Slf4j
@Service
public class DataUtilsApk {

    @Autowired
    private TerminalMapper terminalMapper;

    @Autowired
    private ZNSTaskMapper znsTaskMapper;

    @Autowired
    private OperateHistoryMapper operateHistoryMapper;

    @Autowired
    private BoxAlarmService boxAlarmService;
    private static final byte FRAME = 0x7E;

    public void analysisData(byte[] data, String numbers) {
        //log.info("contentData-------------" + byte2HexStr(data));
        byte contentFrameStart = data[0];
        if (FRAME == contentFrameStart) {
            byte[] contentVersion = new byte[]{data[1], data[2]};
            byte[] contentCode = new byte[]{data[3], data[4]};
            byte[] imei = subBytes(data, 5, 12);
            byte[] functionCode = new byte[]{data[17], data[18]};
            byte frameType = data[19];
            byte[] contentData = new byte[0];

            if ((functionCode[0] & 0xff) == 68) {
                int year, month, day, hour, minutes, seconds;
                String time = "";
                switch (functionCode[1] & 0xff) {
                    case 1:
                        contentData = subBytes(data, 20, 6);
                        year = 2000 + contentData[0] & 0xff;
                        month = contentData[1] & 0xff;
                        day = contentData[2] & 0xff;
                        hour = contentData[3] & 0xff;
                        minutes = contentData[4] & 0xff;
                        seconds = contentData[5] & 0xff;
                        time = year + "/" + month + "/" + day + " " + hour + ":" + minutes + ":" + seconds;
                        break;
                    case 0:
                    case 2:
                    case 4:
                        decodeStatus(data, numbers);
                        break;
                    case 3:
                        contentData = subBytes(data, 20, 7);
                        year = 2000 + contentData[0] & 0xff;
                        month = contentData[1] & 0xff;
                        day = contentData[2] & 0xff;
                        hour = contentData[3] & 0xff;
                        minutes = contentData[4] & 0xff;
                        seconds = contentData[5] & 0xff;

                        time = year + "/" + month + "/" + day + " " + hour + ":" + minutes + ":" + seconds;

                        int lock = contentData[6] & 0xff;
                        break;
                    case 17:
                        contentData = subBytes(data, 20, 7);
                        year = 2000 + contentData[0] & 0xff;
                        month = contentData[1] & 0xff;
                        day = contentData[2] & 0xff;
                        hour = contentData[3] & 0xff;
                        minutes = contentData[4] & 0xff;
                        seconds = contentData[5] & 0xff;

                        time = year + "/" + month + "/" + day + " " + hour + ":" + minutes + ":" + seconds;
                        int open = contentData[6] & 0xff;
                        break;
                    case 18:
                        contentData = subBytes(data, 20, 7);
                        year = 2000 + contentData[0] & 0xff;
                        month = contentData[1] & 0xff;
                        day = contentData[2] & 0xff;
                        hour = contentData[3] & 0xff;
                        minutes = contentData[4] & 0xff;
                        seconds = contentData[5] & 0xff;

                        time = year + "/" + month + "/" + day + " " + hour + ":" + minutes + ":" + seconds;
                        int upFlag = contentData[6] & 0xff;
                        switch (upFlag) {
                            case 1:
                                int result = contentData[7] & 0xff;
                                switch (result) {
                                    case 1:
                                        System.out.println("成功");
                                        break;
                                    case 0:
                                        System.out.println("失败");
                                        break;
                                    case 3:
                                        System.out.println("厂家不符");
                                        break;
                                    case 4:
                                        System.out.println("标识型号不符");
                                        break;
                                    default:
                                        break;
                                }
                                break;
                            case 2:
                                byte[] b2 = subBytes(data, 27, 10);
                                break;
                            case 3:
                                byte[] b3 = subBytes(data, 27, 9);
                                break;
                            case 4:
                                byte[] b4 = subBytes(data, 27, 9);
                                break;
                            default:
                                break;
                        }
                        break;
                    case 19:
                        contentData = subBytes(data, 20, 7);
                        year = 2000 + contentData[0] & 0xff;
                        month = contentData[1] & 0xff;
                        day = contentData[2] & 0xff;
                        hour = contentData[3] & 0xff;
                        minutes = contentData[4] & 0xff;
                        seconds = contentData[5] & 0xff;
                        time = year + "/" + month + "/" + day + " " + hour + ":" + minutes + ":" + seconds;
                        break;
                    case 20:
                        contentData = subBytes(data, 20, 66);
                        year = 2000 + contentData[0] & 0xff;
                        month = contentData[1] & 0xff;
                        day = contentData[2] & 0xff;
                        hour = contentData[3] & 0xff;
                        minutes = contentData[4] & 0xff;
                        seconds = contentData[5] & 0xff;
                        time = year + "/" + month + "/" + day + " " + hour + ":" + minutes + ":" + seconds;

                        byte[] factoryCode = subBytes(contentData, 6, 4);
                        byte[] proCode = subBytes(contentData, 10, 2);
                        byte[] softVersion = subBytes(contentData, 12, 2);
                        byte[] nbFactory = subBytes(contentData, 14, 8);
                        byte[] nbVersion = subBytes(contentData, 22, 8);
                        byte[] nbModel = subBytes(contentData, 30, 8);
                        byte[] outBatch = subBytes(contentData, 38, 8);
                        break;
                    case 21:
                        contentData = subBytes(data, 20, 11);
                        year = 2000 + contentData[0] & 0xff;
                        month = contentData[1] & 0xff;
                        day = contentData[2] & 0xff;
                        hour = contentData[3] & 0xff;
                        minutes = contentData[4] & 0xff;
                        seconds = contentData[5] & 0xff;
                        time = year + "/" + month + "/" + day + " " + hour + ":" + minutes + ":" + seconds;

                        int dataLength = bytes2int(new byte[]{contentData[6], contentData[7]});
                        int num = bytes2int(new byte[]{contentData[8], contentData[9]});
                        int picType = contentData[8] & 0xff;
                        switch (picType) {
                            case 1:
                                System.out.println("bmp");
                                break;
                            case 2:
                                System.out.println("jpg");
                                break;
                            case 3:
                                System.out.println("jpeg");
                                break;
                            case 4:
                                System.out.println("png");
                                break;
                            case 5:
                                System.out.println("gif");
                                break;
                            case 6:
                                System.out.println("tif");
                                break;
                            case 7:
                                System.out.println("tga");
                                break;
                            case 8:
                                System.out.println("raw");
                                break;
                            case 9:
                                System.out.println("wmf");
                                break;
                            default:
                                break;
                        }
                        break;
                    case 22:
                        break;
                    default:
                        break;
                }
            }

            byte[] Crc = subBytes(data, contentData.length + 20, 2);
            byte[] contentFrameEnd = subBytes(data, contentData.length + 22, 1);
        }
    }

    public static byte[] subBytes(byte[] src, int begin, int count) {
        byte[] bs = new byte[count];
        System.arraycopy(src, begin, bs, 0, count);
        return bs;
    }

    public static int bytes2int(byte[] bytes) {
        int result = 0;
        if (bytes.length == 2) {
            int a = (bytes[0] & 0xff) << 8;//说明二
            int b = (bytes[1] & 0xff);
            result = a | b;
        }
        return result;
    }

    private void decodeStatus(byte[] data, String numbers) {
        byte[] contentData;
        if (data.length > 53) {
            contentData = subBytes(data, 20, 70);
        } else {
            contentData = subBytes(data, 20, 30);
        }

        int year = 2000 + (contentData[0] & 0xff);
        System.out.println("年：" + year);
        int month = contentData[1] & 0xff;
        System.out.println("月：" + month);
        int day = contentData[2] & 0xff;
        int hour = contentData[3] & 0xff;
        int minutes = contentData[4] & 0xff;
        int seconds = contentData[5] & 0xff;
        String time = year + "-" + month + "-" + day + " " + hour + ":" + minutes + ":" + seconds;

        System.out.println("时间：" + time);
        int status = contentData[6] & 0xff;
        String door = new BigInteger(1, new byte[]{contentData[6]}).toString(2);
        while (door.length() < 8) {
            door = String.format("0%s", door);
        }

        int door1 = Integer.parseInt(door.substring(7));
        int door2 = Integer.parseInt(door.substring(6, 7));
        int door3 = Integer.parseInt(door.substring(5, 6));
        int door4 = Integer.parseInt(door.substring(4, 5));
        int lock1 = Integer.parseInt(door.substring(3, 4));
        int lock2 = Integer.parseInt(door.substring(2, 3));
        int lock3 = Integer.parseInt(door.substring(1, 2));
        int lock4 = Integer.parseInt(door.substring(0, 1));

        System.out.println("门状态1：" + door1);
        System.out.println("门状态2：" + door2);
        System.out.println("门状态3：" + door3);
        System.out.println("门状态4：" + door4);

        System.out.println("锁状态1：" + lock1);
        System.out.println("锁状态2：" + lock2);
        System.out.println("锁状态3：" + lock3);
        System.out.println("锁状态4：" + lock4);

        int type = contentData[7] & 0xff;
        switch (type) {
            case 0:
                System.out.println("光敏正常");
                break;
            case 1:
                System.out.println("光敏告警");
                break;
            case 255:
                System.out.println("光敏无");
                break;
            default:
                break;
        }

        int type1 = contentData[8] & 0xff;
        switch (type1) {
            case 0:
                System.out.println("水浸正常");
                break;
            case 1:
                System.out.println("水浸告警");
                break;
            case 255:
                System.out.println("水浸无");
                break;
            default:
                break;
        }

        int temp = contentData[9];
        System.out.println("温度：" + temp);
        int hum = contentData[10] & 0xff;
        System.out.println("湿度：" + hum);
        int vol = bytes2int(new byte[]{contentData[11], contentData[12]});
        System.out.println("电池电压：" + vol);
        int signal = bytes2int(new byte[]{contentData[13], contentData[14]});
        System.out.println("信号强度：" + signal);
        int SNR = bytes2int(new byte[]{contentData[15], contentData[16]});
        System.out.println("信噪比：" + SNR);


        int lockHandle1 = contentData[17] & 0x1;
        int lockHandle2 = contentData[17] >> 1 & 0x1;
        int lockHandle3 = contentData[17] >> 2 & 0x1;
        int lockHandle4 = contentData[17] >> 3 & 0x1;

        System.out.println("锁柄1：" + lockHandle1);
        System.out.println("锁柄2：" + lockHandle2);
        System.out.println("锁柄3：" + lockHandle3);
        System.out.println("锁柄4：" + lockHandle4);

        byte[] ob1 = new byte[]{contentData[18], contentData[19]};
        byte[] ob2 = new byte[]{contentData[20], contentData[21]};
        byte[] ob3 = subBytes(contentData, 22, 6);
        byte[] ob4 = new byte[]{contentData[28], contentData[29]};


        Terminal box = terminalMapper.queryTrunkSn(numbers);
        if (box != null) {
            OperateHistory operateHistory = new OperateHistory();
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat();
            try {
                Date parse = simpleDateFormat.parse(time);
                String s = parse.toString();
                operateHistory.setOperateTime(s);
            } catch (Exception e) {
                log.info("系统异常");
            }

            operateHistory.setMac("");
            if (lockHandle1 == 0) {
                operateHistory.setOperateType("02-关锁");
                operateHistory.setLockStatus("02-关闭");
            }

            if (lockHandle1 == 1) {
                operateHistory.setOperateType("01-开锁");
                operateHistory.setLockStatus("01-开启");
            }
            operateHistory.setIsFrom("2");
            List<TaskZNSDTO> missionList = znsTaskMapper.selectByOneBoxId(box.getTrunkSn());
            if (missionList.size() != 1) {
                operateHistory.setMissionId("0");
                operateHistory.setMissionType("0");
                operateHistory.setStatus("0");
                operateHistory.setIsWorkTime("0");
            } else {
                TaskZNSDTO mission = missionList.get(0);
                operateHistory.setMissionId(mission.getTaskId());
                operateHistory.setMissionType("2");
                Date parse = null;
                try {
                    parse = simpleDateFormat.parse(mission.getStartTime());
                    Date endTime = simpleDateFormat.parse(mission.getDeadLineDate());
                    String s = endTime.toString();
                    long end = (long) Integer.parseInt(s);

                    String startTime = parse.toString();
                    long start = (long) Integer.parseInt(startTime);
                    if (start <= System.currentTimeMillis()
                            && end >= System.currentTimeMillis()) {
                        operateHistory.setStatus("2");
                        operateHistory.setIsWorkTime("2");
                    } else {
                        operateHistory.setStatus("1");
                        operateHistory.setIsWorkTime("1");
                    }
                } catch (ParseException e) {
                    e.printStackTrace();
                }


            }
            String trunkLockOne = box.getTrunkLockOne();
            String trunkLockTwo = box.getTrunkLockTwo();
            List<String> locks = new ArrayList<>();
            if ((!"".equals(trunkLockOne)) && trunkLockOne != null) {
                locks.add(trunkLockOne);
            }
            if ((!"".equals(trunkLockTwo)) && trunkLockTwo != null) {
                locks.add(trunkLockTwo);
            }
            if (locks.size() > 1) {
                operateHistory.setLockId("0");
            } else {
                operateHistory.setLockId(locks.get(0));
            }
            operateHistory.setUser1("0");
            operateHistory.setUser2("0");
            operateHistory.setOrgId(box.getOrgId());
            operateHistory.setCollectTime(new Date());
            operateHistory.setKeyId(0);
            operateHistoryMapper.insert(operateHistory);

            box.setDoorStatus(door1 == 0 ? "1" : "0");
            box.setLockStatusOne(lock1 == 0 ? "1" : "0");
            box.setLockStatusTwo(lock2 == 0 ? "1" : "0");
            if (contentData.length > 30) {
                byte[] latitude = subBytes(contentData, 30, 20);
                System.out.println("latitude-------------" + AsciiToString(latitude));
                byte[] longitude = subBytes(contentData, 50, 20);
                System.out.println("longitude-------------" + AsciiToString(longitude));

                String lat = AsciiToString(latitude);
                String lon = AsciiToString(longitude);

                double lati = "".equals(lat) ? 0 : Double.parseDouble(lat) / 100d;
                double longit = "".equals(lon) ? 0 : Double.parseDouble(lon) / 100d;

                double latiInteger = Math.floor(lati);
                double longitInteger = Math.floor(longit);
                System.out.println(latiInteger);
                System.out.println(longitInteger);

                System.out.println((lati - latiInteger) * 100);
                System.out.println((longit - longitInteger) * 100);

                double resultLati = latiInteger + ((lati - latiInteger) * 100) / 60;
                double resultLongit = longitInteger + ((longit - longitInteger) * 100) / 60;

                System.out.println(resultLati);
                System.out.println(resultLongit);

                if (resultLati != 0 && resultLongit != 0) {
                    Point point = CoordinateConversion.wgs_gcj_encrypts(resultLati, resultLongit);
                    point = CoordinateConversion.google_bd_encrypt(point.getLat(), point.getLng());
                    resultLati = point.getLat();
                    resultLongit = point.getLng();
                }
                StringBuilder coordinates = new StringBuilder();
                JSONObject jsonObject = (JSONObject) boxAlarmService.addAlarm(String.valueOf(resultLongit), String.valueOf(resultLati), lock1, door1, numbers);

                if (resultLongit != 0) {
                    coordinates.append(resultLongit + "" + ",");
                }
                if (resultLati != 0) {
                    coordinates.append(resultLati + "");
                }
                box.setCoordinates(coordinates.toString());
                ;
            }
            terminalMapper.updateByPrimaryKey(box);
        }
        byte[] crcData = subBytes(data, 1, data.length - 4);
        System.out.println("contentData-------------" + byte2HexStr(crcData));
        //System.out.println(byte2HexStr(CrcUtils.CRC16(crcData)));
        if (CrcUtils.isPassCRC(crcData, 2)) {
            System.out.println("验证通过");
        } else {
            System.out.println("验证失败");
        }


    }

    public static String byteToBit(byte b) {
        return "" + (byte) ((b >> 7) & 0x1) +
                (byte) ((b >> 6) & 0x1) +
                (byte) ((b >> 5) & 0x1) +
                (byte) ((b >> 4) & 0x1) +
                (byte) ((b >> 3) & 0x1) +
                (byte) ((b >> 2) & 0x1) +
                (byte) ((b >> 1) & 0x1) +
                (byte) ((b >> 0) & 0x1);
    }


    /* * bytes转换成十六进制字符串
     *
     * @param b byte数组
     * @return String 每个Byte值之间空格分隔*/

    public static String byte2HexStr(byte[] b) {
        String stmp = "";
        StringBuilder sb = new StringBuilder("");
        for (int n = 0; n < b.length; n++) {
            stmp = Integer.toHexString(b[n] & 0xFF);
            sb.append((stmp.length() == 1) ? "0" + stmp : stmp);
            sb.append(" ");
        }
        return sb.toString().toUpperCase().trim();
    }



    /* * bytes转换成十六进制字符串
     *
     * @param b byte数组
     * @return String 每个Byte值之间空格分隔*/

    public static String byteToHexStr(byte[] b) {
        String stmp = "";
        StringBuilder sb = new StringBuilder("");
        for (int n = 0; n < b.length; n++) {
            stmp = Integer.toHexString(b[n] & 0xFF);
            sb.append((stmp.length() == 1) ? "0" + stmp : stmp);
        }
        return sb.toString().toUpperCase().trim();
    }



    /* * Hex字符串转byte
     *
     * @param inHex 待转换的Hex字符串
     * @return 转换后的byte*/

    public static byte hexToByte(String inHex) {
        return (byte) Integer.parseInt(inHex, 16);
    }


    /* * hex字符串转byte数组
     *
     * @param inHex 待转换的Hex字符串
     * @return 转换后的byte数组结果*/

    public static byte[] hexToByteArray(String inHex) {
        System.out.println(inHex);
        int hexlen = inHex.length();
        byte[] result;
        if (hexlen % 2 == 1) {
            //奇数
            hexlen++;
            result = new byte[(hexlen / 2)];
            inHex = "0" + inHex;
        } else {
            //偶数
            result = new byte[(hexlen / 2)];
        }
        int j = 0;
        for (int i = 0; i < hexlen; i += 2) {
            result[j] = hexToByte(inHex.substring(i, i + 2));
            j++;
        }
        return result;
    }


    private final static String[] HEX_ARRAY = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"};

    public static String byteToHex(int n) {
        if (n < 0) {
            n = n + 256;
        }
        int d1 = n / 16;
        int d2 = n % 16;
        return HEX_ARRAY[d1] + HEX_ARRAY[d2];
    }

    public static String AsciiToString(byte[] result2) {
        StringBuilder sbu = new StringBuilder();
        for (byte b : result2) {
            if (0 == b) {
                break;
            }
            sbu.append((char) Integer.parseInt(String.valueOf(b)));
        }
        return sbu.toString();
    }

    public static String leftShift(String string, int n) {
        String newStr = string + string;
        String rString = "";
        for (int i = 0; i < string.length(); i++) {
            rString += newStr.charAt(i + n);
        }

        return rString;
    }

}
